/*
 * Copyright (c) 2023-2025 elsfs Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.elsfs.cloud.starter.login.configuration;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elsfs.cloud.api.security.service.SecurityUserService;
import org.elsfs.cloud.common.properties.ElsfsSecurityProperties;
import org.elsfs.cloud.common.security.authentication.ReactiveJwtUserIdAuthenticationConverter;
import org.elsfs.cloud.common.security.configurer.AbstractReactiveSecurityCustomConfiguration;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.authentication.UserDetailsRepositoryReactiveAuthenticationManager;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.server.SecurityWebFilterChain;

/**
 * 登录认证配置
 *
 * @author zeng
 */
@AutoConfiguration
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
@EnableConfigurationProperties(ElsfsSecurityProperties.class)
@RequiredArgsConstructor
@Slf4j
@EnableWebFluxSecurity
@EnableMethodSecurity
public class ReactiveSecurityConfiguration extends AbstractReactiveSecurityCustomConfiguration {
  private final SecurityUserService securityUserService;

  @Bean
  ReactiveJwtUserIdAuthenticationConverter jwtUserIdAuthenticationConverter() {
    return new ReactiveJwtUserIdAuthenticationConverter(securityUserService);
  }

  @Bean
  ReactiveAuthenticationManager reactiveAuthenticationManager(
      ReactiveUserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
    UserDetailsRepositoryReactiveAuthenticationManager manager =
        new UserDetailsRepositoryReactiveAuthenticationManager(userDetailsService);
    manager.setPasswordEncoder(passwordEncoder);
    return manager;
  }

  @Bean
  @Order(2)
  SecurityWebFilterChain defaultSecurityWebFilterChain(ServerHttpSecurity http) {
    return http.formLogin(Customizer.withDefaults()).build();
  }

  @Override
  public void afterPropertiesSet() throws Exception {}
}
